package com.ermax.aircond.maintain.service.impl;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ermax.aircond.common.dao.UserDetailDao;
import com.ermax.aircond.common.dao.UserGroupDao;
import com.ermax.aircond.common.domain.UserDetail;
import com.ermax.aircond.common.domain.UserGroup;
import com.ermax.aircond.maintain.dao.BuildingDao;
import com.ermax.aircond.maintain.dao.FloorDao;
import com.ermax.aircond.maintain.dao.MachineDao;
import com.ermax.aircond.maintain.dao.RoomDao;
import com.ermax.aircond.maintain.domain.Building;
import com.ermax.aircond.maintain.domain.Floor;
import com.ermax.aircond.maintain.domain.Machine;
import com.ermax.aircond.maintain.domain.Room;
import com.ermax.aircond.maintain.service.MaintainService;

@Service("maintainService")
public class MaintainServiceImpl implements MaintainService, Serializable {

	private static final long serialVersionUID = 1L;
	@Autowired
	private UserGroupDao userGroupDao;
	@Autowired
	private UserDetailDao userDetailDao;
	@Autowired
	private BuildingDao buildingDao;
	@Autowired
	private FloorDao floorDao;
	@Autowired
	private RoomDao roomDao;
	@Autowired
	private MachineDao machineDao;

	@Override
	@Transactional(readOnly = true)
	public UserGroup getUserGroupById(long id) throws Exception{
		return userGroupDao.getById(id);
	}
	
	@Override
	@Transactional(readOnly = true)
	public List<UserGroup> getAllUserGroups() throws Exception {
		return userGroupDao.findAll();
	}

	@Override
	@Transactional(readOnly = true)
	public List<UserGroup> getUserGroups(String search) throws Exception {
		return userGroupDao.findUserGroupByKeyword(search);
	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void createUserGroup(UserGroup userGroup, String userName) throws Exception {
		Date currentDate = new Date();
		userGroup.setCreateUser(userName);
		userGroup.setCreateDate(currentDate);
		userGroup.setUpdateUser(userName);
		userGroup.setUpdateDate(currentDate);
		userGroupDao.create(userGroup);
	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void updateUserGroup(UserGroup userGroup, String userName) throws Exception {
		Date currentDate = new Date();
		userGroup.setUpdateUser(userName);
		userGroup.setUpdateDate(currentDate);
		userGroupDao.update(userGroup);

	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void deleteUserGroup(UserGroup userGroup) throws Exception {
		userGroupDao.delete(userGroup);
	}

	@Override
	@Transactional(readOnly = true)
	public List<UserDetail> getAllUserDetails() throws Exception {
		return userDetailDao.findAll();
	}

	@Override
	public List<UserDetail> getUserDetails(String search) throws Exception {
		return getUserDetails(null, search);
	}

	@Override
	public List<UserDetail> getUserDetails(UserGroup userGroup) throws Exception {
		return getUserDetails(userGroup, null);
	}

	@Override
	@Transactional(readOnly = true)
	public List<UserDetail> getUserDetails(UserGroup userGroup, String search) throws Exception {
		return userDetailDao.findUserDetails(userGroup, search);
	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void createUserDetail(UserDetail userDetail, String userName) throws Exception {
		Date currentDate = new Date();
		userDetail.setCreateDate(currentDate);
		userDetail.setCreateUser(userName);
		userDetail.setUpdateDate(currentDate);
		userDetail.setUpdateUser(userName);
		userDetailDao.create(userDetail);
	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void updateUserDetail(UserDetail userDetail, String userName) throws Exception {
		userDetail.setUpdateDate(new Date());
		userDetail.setUpdateUser(userName);
		userDetailDao.update(userDetail);
	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void deleteUserDetail(UserDetail userDetail) throws Exception {
		userDetailDao.delete(userDetail);

	}
	
	@Override
	@Transactional(readOnly = true)
	public Building getBuildingById(long id) throws Exception{
		return buildingDao.getById(id);
	}

	@Override
	@Transactional(readOnly = true)
	public List<Building> getAllBuildings() throws Exception {
		return buildingDao.findAll();
	}

	@Override
	@Transactional(readOnly = true)
	public List<Building> getBuildings(String search) throws Exception {
		return buildingDao.findBuildings(search);
	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void createBuilding(Building building, String userName) throws Exception {
		Date currentDate = new Date();
		building.setCreateDate(currentDate);
		building.setCreateUser(userName);
		building.setUpdateDate(currentDate);
		building.setUpdateUser(userName);
		buildingDao.create(building);
	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void updateBuilding(Building building, String userName) throws Exception {
		Date currentDate = new Date();
		building.setUpdateDate(currentDate);
		building.setUpdateUser(userName);
		buildingDao.update(building);
	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void deleteBuilding(Building building) throws Exception {
		buildingDao.delete(building);
	}
	
	@Override
	@Transactional(readOnly = true)
	public Floor getFloorById(long id) throws Exception{
		return floorDao.getById(id);
	}

	@Override
	@Transactional(readOnly = true)
	public List<Floor> getAllFloors() throws Exception {
		return floorDao.findAll();
	}

	@Override
	public List<Floor> getFloors(String search) throws Exception {
		return getFloors(null, search);
	}

	@Override
	public List<Floor> getFloors(Building building) throws Exception {
		return getFloors(building, null);
	}

	@Override
	@Transactional(readOnly = true)
	public List<Floor> getFloors(Building building, String search) throws Exception {
		return floorDao.findFloors(building, search);
	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void createFloor(Floor floor, String userName) throws Exception {
		Date currentDate = new Date();
		floor.setCreateDate(currentDate);
		floor.setCreateUser(userName);
		floor.setUpdateDate(currentDate);
		floor.setUpdateUser(userName);
		floorDao.create(floor);
	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void updateFloor(Floor floor, String userName) throws Exception {
		Date currentDate = new Date();
		floor.setUpdateDate(currentDate);
		floor.setUpdateUser(userName);
		floorDao.update(floor);
	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void deleteFloor(Floor floor) throws Exception {
		floorDao.delete(floor);
	}

	@Override
	@Transactional(readOnly = true)
	public Room getRoomById(long id) throws Exception {
		return roomDao.getById(id);
	}
	
	@Override
	@Transactional(readOnly = true)
	public List<Room> getAllRooms() throws Exception {
		return roomDao.findAll();
	}

	@Override
	public List<Room> getRooms(Building building) throws Exception {
		return getRooms(building, null, null);
	}

	@Override
	public List<Room> getRooms(Building building, Floor floor) throws Exception {
		return getRooms(building, floor, null);
	}

	@Override
	@Transactional(readOnly = true)
	public List<Room> getRooms(Building building, Floor floor, String search) throws Exception {
		return roomDao.findRooms(building, floor, search);
	}

	@Override
	public List<Room> getRooms(Floor floor) throws Exception {
		return getRooms(null, floor, null);
	}

	@Override
	public List<Room> getRooms(Floor floor, String search) throws Exception {
		return getRooms(null, floor, search);
	}

	@Override
	public List<Room> getRooms(String search) throws Exception {
		return getRooms(null, null, search);
	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void createRoom(Room room, String userName) throws Exception {
		Date currentDate = new Date();
		room.setCreateDate(currentDate);
		room.setCreateUser(userName);
		room.setUpdateDate(currentDate);
		room.setUpdateUser(userName);
		roomDao.create(room);

	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void updateRoom(Room room, String userName) throws Exception {
		Date currentDate = new Date();
		room.setUpdateDate(currentDate);
		room.setUpdateUser(userName);
		roomDao.update(room);
	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void deleteRoom(Room room) throws Exception {
		roomDao.delete(room);
	}

	@Override
	@Transactional(readOnly = true)
	public List<Machine> getMachines() throws Exception {
		return machineDao.findAll();
	}

	@Override
	public List<Machine> getMachines(Building building) throws Exception {
		return getMachines(building, null, null, null);
	}

	@Override
	public List<Machine> getMachines(Building building, Floor floor) throws Exception {
		return getMachines(building, floor, null, null);
	}

	@Override
	public List<Machine> getMachines(Building building, Floor floor, Room room) throws Exception {
		return getMachines(building, floor, room, null);
	}

	@Override
	@Transactional(readOnly = false)
	public List<Machine> getMachines(Building building, Floor floor, Room room, String search) throws Exception {
		return machineDao.findMachines(building, floor, room, search);
	}

	@Override
	public List<Machine> getMachines(Floor floor) throws Exception {
		return getMachines(null, floor, null, null);
	}

	@Override
	public List<Machine> getMachines(Floor floor, Room room) throws Exception {
		return getMachines(null, floor, room, null);
	}

	@Override
	public List<Machine> getMachines(Floor floor, Room room, String search) throws Exception {
		return getMachines(null, floor, room, search);
	}

	@Override
	public List<Machine> getMachines(Room room) throws Exception {
		return getMachines(null, null, room, null);
	}

	@Override
	public List<Machine> getMachines(Room room, String search) throws Exception {
		return getMachines(null, null, room, search);
	}

	@Override
	public List<Machine> getMachines(String search) throws Exception {
		return getMachines(null, null, null, search);
	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void createMachine(Machine machine, String userName) throws Exception {
		Date currentDate = new Date();
		machine.setCreateDate(currentDate);
		machine.setCreateUser(userName);
		machine.setUpdateDate(currentDate);
		machine.setUpdateUser(userName);
		machineDao.create(machine);

	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void updateMachine(Machine machine, String userName) throws Exception {
		Date currentDate = new Date();
		machine.setUpdateDate(currentDate);
		machine.setUpdateUser(userName);
		machineDao.update(machine);
	}

	@Override
	@Transactional
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	public void deleteMachine(Machine machine) throws Exception {
		machineDao.delete(machine);

	}

	@Override
	@Transactional
	public Floor getFloorDetail(long id) throws Exception {
		Floor floor = floorDao.getById(id);
		floor.getFloorPlan();
		return floor;
	}

}
